package com.iss.card.webservice;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;

import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.iss.card.common.Tools;
import com.iss.card.webservice.WebServiceAsyncServiceHelper.OperationInfo;

public class WebServiceAsyncServiceHelper extends
		AsyncTask<OperationInfo, Integer, OperationInfo> {

	private static final String TAG = WebServiceAsyncServiceHelper.class.getSimpleName();

	public static final Object lockObj = new Object();
	public static final Object lockObjResult = new Object();
	/**http post*/
	public static final int TYPE_HTTP_POST = 0;
//	/**http get string*/
//	public static final int TYPE_HTTP_GET_STRING = 1;
	/**http get stream*/
	public static final int TYPE_HTTP_GET_INSTREAM = 2;

	@Override
	protected OperationInfo doInBackground(OperationInfo... info) {
		synchronized (lockObj) {
			return executeServiceCall(info[0]);
		}
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		super.onProgressUpdate(values);
	}

	@Override
	protected void onPostExecute(OperationInfo result) {
		synchronized (lockObjResult) {
			super.onPostExecute(result);
			Message reply = result.handler.obtainMessage(result.token);
			reply.obj = result;
			reply.arg1 = result.op;
			reply.sendToTarget();
			
//			Log.d(TAG,
//					"getLastCancelableOperation -> Operation:"
//							+ Operation.opToChar(result.op) + " token:"
//							+ result.token);
		}
	}

	/**
	 * 执锟斤拷锟届步
	 * 
	 * @param info
	 *            锟秸硷拷锟斤拷息
	 */
	public void queueOperation(WebServiceAsyncServiceHelper wash ,OperationInfo info) {
		wash.execute(info);
	}

	protected static class OperationInfo {
		public String[] parameterName;
		public String[] parameterValues;
		public String servicePortName;
		public Handler handler;
		public int op;
		public Object result;
		public int token;
		public int index;
	}

	/**
	 * 执锟叫凤拷锟斤拷锟斤拷锟�
	 * 
	 * @param info
	 *            锟斤拷锟斤拷锟斤拷息
	 * @return OperationInfo
	 */
	static private OperationInfo executeServiceCall(OperationInfo info) {
		OperationInfo opInfo = null;
		switch (info.index) {
			case TYPE_HTTP_POST:
				opInfo = httpPostInfo(info);
				break;
			case TYPE_HTTP_GET_INSTREAM:
//			case TYPE_HTTP_GET_STRING:
				opInfo = httphttpGetInfo(info);
				break;
			default:
				break;
			}
		return opInfo;
	}
	/**
	 * http get request.
	 * @param info
	 * @return
	 */
	
	private static OperationInfo httphttpGetInfo(OperationInfo info) {
		String url = WebServiceManager.serviceURL + "/" + info.servicePortName + ".aspx";
		try {
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
			HttpConnectionParams.setSoTimeout(httpParams, 10000);
			HttpResponse httpResponse = null;
			if(info.parameterName != null && info.parameterValues != null &&
					info.parameterName.length !=0 && info.parameterValues.length != 0){
				String tmp = "";
				for (int i = 0; i < info.parameterName.length; i++) {
					tmp = tmp + info.parameterName[i] + "=" + URLEncoder.encode(info.parameterValues[i], "UTF-8");
					if(i < info.parameterName.length-1){
						tmp = tmp + "&";
					}
				}
				Log.i(TAG, "[" + url + "?" + tmp + "]");
				url = url + "?" + URLEncoder.encode(Tools.triableEncode(tmp), "UTF-8");
			} else {
				Log.i(TAG, "[" + url + "]");
			}
			
			Log.i(TAG, "encoded: [" + url + "]");
			HttpGet httpGet = new HttpGet(url);
			httpResponse = new DefaultHttpClient(httpParams).execute(httpGet);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				return gatherInformation(info, httpResponse.getEntity().getContent());
			} else {
				Log.e(TAG, "httpGetInfo:error code is "+ httpResponse.getStatusLine().getStatusCode());
			}
		} catch (ClientProtocolException e) {
			Log.e(TAG, "httpGetInfo:ClientProtocolException");
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(TAG, "httpGetInfo:IOException");
			e.printStackTrace();
		}
		return gatherInformationByNetworkSnail(info);
	
	}
	
	/**
	 * http get request.
	 * @param info
	 * @return
	 */
	public static Object httphttpGetInfo(String str) {
		String url = WebServiceManager.serviceURL + "/" + str + ".aspx";
		Log.i(TAG, url);
		try {
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
			HttpConnectionParams.setSoTimeout(httpParams, 10000);
			HttpResponse httpResponse = null;
			// 锟斤拷1锟斤拷锟斤拷锟斤拷锟斤拷HttpGet锟斤拷锟斤拷
			HttpGet httpGet = new HttpGet(url);
			// 锟斤拷2锟斤拷锟斤拷使锟斤拷execute锟斤拷锟斤拷锟斤拷锟斤拷HTTP GET锟斤拷锟襟，诧拷锟斤拷锟斤拷HttpResponse锟斤拷锟斤拷
			httpResponse = new DefaultHttpClient(httpParams).execute(httpGet);
			// 锟叫讹拷锟斤拷锟斤拷锟斤拷应状态锟诫，状态锟斤拷为200锟斤拷示锟斤拷锟斤拷顺晒锟斤拷锟接︼拷丝突锟斤拷说锟斤拷锟斤拷锟�
			System.out.println(httpResponse.getStatusLine().getStatusCode());
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				// 锟斤拷3锟斤拷锟斤拷使锟斤拷getEntity锟斤拷锟斤拷锟斤拷梅锟斤拷亟锟斤拷
//				if(info.index == TYPE_HTTP_GET_STRING){
//					String result = EntityUtils.toString(httpResponse.getEntity()).replace("\r", "");
//					Log.i(TAG, "httpGetInfo:result = " + result.toString());
//					return gatherInformation(info, result);
//				}else{
					return httpResponse.getEntity().getContent();
//				}
			} else {
				Log.e(TAG, "httpGetInfo:error code is "+ httpResponse.getStatusLine().getStatusCode());
			}
		} catch (ClientProtocolException e) {
			Log.e(TAG, "httpGetInfo:ClientProtocolException");
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(TAG, "httpGetInfo:IOException");
			e.printStackTrace();
		}
		return null;
	
	}
	

	/**
	 * http post request.
	 * @param info
	 * @return 
	 */
	static OperationInfo httpPostInfo(OperationInfo info){
		
		try {
			BasicHttpParams httpParams = new BasicHttpParams();  
			HttpConnectionParams.setConnectionTimeout(httpParams, 5000);  
			HttpConnectionParams.setSoTimeout(httpParams, 5000);
			String url = WebServiceManager.serviceURL + "/" + info.servicePortName + ".aspx";
			Log.i(TAG, url);
			HttpResponse httpResponse = null;
			// 锟斤拷1锟斤拷锟斤拷锟斤拷锟斤拷HttpPost锟斤拷锟斤拷
			HttpPost httpPost = new HttpPost(url);
			// 锟斤拷锟斤拷HTTP POST锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷NameValuePair锟斤拷锟斤拷
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			if(info.parameterName != null){
				int parameterSzie = info.parameterName.length;
				for (int i = 0; i < parameterSzie; i++) {
					params.add(new BasicNameValuePair(info.parameterName[i], info.parameterValues[i]));
				}
			}
//			params.add(new BasicNameValuePair("Mobile", "13312341234"));
//			params.add(new BasicNameValuePair("Password", "000"));
			// 锟斤拷锟斤拷HTTP POST锟斤拷锟斤拷锟斤拷锟�
			httpPost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
			// 锟斤拷2锟斤拷锟斤拷使锟斤拷execute锟斤拷锟斤拷锟斤拷锟斤拷HTTP POST锟斤拷锟襟，诧拷锟斤拷锟斤拷HttpResponse锟斤拷锟斤拷
			httpResponse = new DefaultHttpClient(httpParams).execute(httpPost);
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				// 锟斤拷3锟斤拷锟斤拷使锟斤拷getEntity锟斤拷锟斤拷锟斤拷梅锟斤拷亟锟斤拷
//				String result = EntityUtils.toString(httpResponse.getEntity()).replaceAll("\r", "");
				// 去锟斤拷锟斤拷锟截斤拷锟斤拷械锟�\r"锟街凤拷锟斤拷锟斤拷锟节斤拷锟斤拷址锟斤拷锟斤拷锟斤拷示一锟斤拷小锟斤拷锟斤拷
//				Log.i(TAG,"httpPostInfo result:"+ result.replaceAll("\r", ""));
				return gatherInformation(info, httpResponse.getEntity().getContent());
			} else {
				Log.e(TAG, "httpPostInfo:error code is "+ httpResponse.getStatusLine().getStatusCode());
			}
		} catch (UnsupportedEncodingException e) {
			Log.e(TAG, "httpPostInfo:UnsupportedEncodingException");
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			Log.e(TAG, "httpPostInfo:ClientProtocolException");
			e.printStackTrace();
		} catch (SocketTimeoutException e) {
			Log.e(TAG, "httpPostInfo:SocketTimeoutException");
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(TAG, "httpPostInfo:IOException");
			e.printStackTrace();
		} 
		return gatherInformationByNetworkSnail(info);
		
	}
	
	
	/**
	 * set retrun info normally.
	 * @param info
	 * @param envelope
	 * @return
	 */
	private static OperationInfo gatherInformation(OperationInfo info, Object result){
//		OperationInfo oInfo = new OperationInfo();
//		oInfo.op = info.op;
//		oInfo.token = info.token;
//		oInfo.handler = info.handler;
		info.result = result;
		return info;
	}
	
	/**
	 * set retrun info exception.
	 * @param info
	 * @param envelope
	 * @return 
	 */
	private static OperationInfo gatherInformationByNetworkSnail(OperationInfo info){
//		OperationInfo oInfo = new OperationInfo();
//		oInfo.op = info.op;
//		oInfo.token = info.token;
//		oInfo.handler = info.handler;
		info.result = null;
		return info;
	}

}
